Skip to content

perf(scheduler): improve utilization and scale#810

Draft
eric-tramel wants to merge 4 commits into
mainfrom
codex/telemetry-scheduler-optimization
Draft

perf(scheduler): improve utilization and scale#810
eric-tramel wants to merge 4 commits into
mainfrom
codex/telemetry-scheduler-optimization

Conversation

@eric-tramel

@eric-tramel eric-tramel commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Improves async generation throughput, model-slot utilization, and large-run scheduler scaling with four targeted changes. The implementation is net +16 nonblank production LoC and adds no public API, dependency, feedback controller, or user tuning knob.

Changes

  • Make bounded-borrow admission work-conserving: a sole runnable scheduling group can use all resource slots, while existing borrow debt gives a newly waiting peer priority as slots are released.
  • Bound fair-queue priority state by active scheduling groups instead of retaining historical task entries.
  • Compact checkpointed completion state after a row group is durably written and all of its workers finish.
  • Write resume metadata after the first durable row group and refresh it at completion; parquet files remain the source of truth for resume progress.

Performance vs. main

End-to-end throughput and utilization

Full-job reservation measurements count each physical endpoint once, including shared-model endpoints. The reported unit is endpoint concurrent-service-capacity slot-hours, a GPU-hours proxy until the inference owner supplies the endpoint-to-GPU allocation.

Workload main This PR Change
Heavy-root/late-peer simulation, wall 36.70 s 34.00 s -7.36%
Heavy-root/late-peer simulation, model-slot utilization 91.55% 98.82% +7.27 pp
Heavy-root/late-peer simulation, idle slot-seconds 24.80 s 3.20 s -87.1%
In-process slow→fast DAG, 32 records 71.18 ms / 449.6 records/s 65.85 ms / 486.0 records/s wall -7.49%, throughput +8.09%, utilization +9.81 pp
In-process slow→fast DAG, 512 records 798.02 ms / 641.6 records/s 783.90 ms / 653.1 records/s wall -1.77%, throughput +1.80%
OpenAI-compatible HTTP DAG, 32 records 0.930 s / 34.4 records/s 0.889 s / 36.0 records/s wall -4.38%, throughput +4.60%, utilization +9.36 pp
OpenAI-compatible HTTP DAG, 256 records 4.044 s / 63.3 records/s 4.026 s / 63.6 records/s wall -0.45%, throughput +0.45%, utilization +3.95 pp
Endpoint-queued HTTP DAG, 64 records 1.950 s / 32.8 records/s 1.967 s / 32.5 records/s wall +0.86%, throughput -0.86%, utilization +0.52 pp; statistically neutral
Calibrated slow→fast corpus, 160,032 requests 105.919 s / 0.7061 slot-h 105.907 s / 0.7060 slot-h wall/reserved -0.01%, full-job utilization 32.45%→32.54%; practical equivalence
Calibrated fast→slow corpus, 160,032 requests 105.839 s / 0.7056 slot-h 106.230 s / 0.7082 slot-h wall/reserved +0.37%, full-job utilization 32.09%→32.06%; practical equivalence
Heterogeneous fork/join corpus, wall 113.485 s 85.979 s -24.238%, slow-endpoint utilization +21.931 pp
Heterogeneous fork/join, full-job endpoint reservation 1.1349 slot-h / 10.227% utilized 0.8598 slot-h / 13.498% utilized reserved -24.238%, idle -26.999%
Five-wide → slow-join → five-wide corpus 212.510 s / 1.06255 slot-h 100.393 s / 0.50196 slot-h wall/reserved -52.760%, idle -56.462%; 99.17% CI [-53.429%, -52.083%]
Five-wide → slow-join → five-wide endpoint flow 6.557% utilized / 23.506% all-provider blackout 13.880% utilized / 3.773% blackout utilization +7.323 pp, blackout -19.733 pp, fast gap p95 -33.8%
Shared-endpoint fairness corpus, wall 122.846 s 123.052 s +0.168%, utilization -0.011 pp; practical equivalence
Dynamic-capacity mixed roots, endpoint cap 2→8 169.564 s / 0.53187 slot-h 171.183 s / 0.53727 slot-h wall +0.956%, reserved +1.016%, idle +3.497%, utilization -0.473 pp; 99.17% CI [-1.209%, +3.168%], inconclusive

Work-conserving admission removes speculative idle capacity while remaining practically equivalent for both slow-before-fast and fast-before-slow calibrated flows. It cannot preempt work already running: in the measured worst case, a late peer started up to 350 ms later when it arrived behind a 400 ms task; borrow debt still gives it the next released slot.

Large-run scheduler and memory scaling

Workload main This PR Change
Completion state, 1M records in 1,000 groups 217.180 MiB 0.059 MiB -99.97%
Completion state, 100k one-row groups 151.899 MiB 8.045 MiB -94.70%
Fair-queue scheduler, 1k records 0.240 s 0.042 s 5.69× faster
Fair-queue scheduler, 10k records 22.794 s 0.462 s 49.34× faster
Fair-queue scheduler, 100k records unfinished at 369.6 s 4.935 s >74.9× faster to cutoff
Fair-queue scheduler, 1M records impractical on the historical-state path 49.085 s 20,373 records/s, no retained priority state

The pathological one-row-group-per-record case retains one compact terminal marker per group: 70.511 MiB at one million groups. With normal buffer sizes, retained completion state is effectively constant relative to record count.

Metadata checkpointing

Workload Change vs. main
Isolated 1M-record metadata loop 8.705 s → 0.336 s (-96.1%)
Heterogeneous fork/join DAG wall -1.630%, throughput +1.657%, utilization +1.289 pp
Shared-endpoint fairness DAG wall -0.054%, throughput +0.054%, utilization +0.032 pp
Five-wide → slow-join → five-wide DAG wall -0.222%, throughput +0.222%, utilization +0.260 pp
Incremental metadata blocking across complex DAGs -99.50% to -99.85%

The shared-endpoint and hourglass cells are practically equivalent on wall time within a ±2% margin, while the heterogeneous fork/join cell improves both throughput and utilization.

Signed-off-by: Eric W. Tramel <eric.tramel@gmail.com>
Signed-off-by: Eric W. Tramel <eric.tramel@gmail.com>
Signed-off-by: Eric W. Tramel <eric.tramel@gmail.com>
Persist resume metadata after the first durable row group and refresh it at completion. Resume already recovers progress from parquet files, avoiding repeated metadata scans and writes without adding a tuning knob.

Add focused cadence coverage and document the resume contract.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant